<!--
 * @Description: 
 * @FilePath: \rs_wms_pc\src\views\basic\storehouse\planView.vue
-->
<!--
 * @Description: 
 * @FilePath: \rs_wms_pc\src\views\basic\storehouse\planView.vue
-->
<template>
  <div class="app-container">
    <div class="flex-row-start-start">
        <div style="width: 200px;">
            <el-tree ref="storeTree" highlight-current :data="storeHouseTree" :props="defaultProps" node-key="no" :current-node-key="$route.params.storeHouseNo" :default-expanded-keys="[$route.params.storeHouseNo]" accordion  @node-click="handleNodeClick">
                <span class="custom-tree-node" slot-scope="{ node, data }">
                    <div 
                        :draggable="node.level!=1"
                        @dragstart="dragStart(data)"
                        @dragover.prevent="dragOver"
                        @dragend="dragEnd(data)">
                        {{ data.no }}
                    </div>
                </span>
            </el-tree>
        </div>
        <!-- 中间绘图区 -->
        <div style="width:100%;">
            <div class="flex-row-between" style="height: 30px;">
                <el-button type="primary" @click="save" size="small">保存</el-button>
                <div>{{selectStore.category==1?'仓库':'库区'}}： {{selectStore.no}}</div>
                <div class="flex-row">
                    <div v-if="selectStore.category==1" class="flex-row">
                        <span class="text">W： </span><el-input-number v-model='selectStore.platW' :min="1" :controls="false" style="width:100px;margin-right:8px" @change="save"/>
                        <span class="text">H： </span><el-input-number v-model='selectStore.platH' :min="1" :controls="false" style="width:100px;margin-right:8px" @change="save"/>
                    </div>
                    <el-dropdown @command="handleCommand">
                        <span class="el-dropdown-link">
                            {{zoom}}<i class="el-icon-arrow-down el-icon--right"></i>
                        </span>
                        <el-dropdown-menu slot="dropdown">
                            <el-dropdown-item command="50%">50%</el-dropdown-item>
                            <el-dropdown-item command="100%">100%</el-dropdown-item>
                            <el-dropdown-item command="150%">150%</el-dropdown-item>
                        </el-dropdown-menu>
                    </el-dropdown>
                </div>
            </div>
            <div ref="dropWrap" class="drop-wrap" @click.self="clearActiveItem" @mouseup="wrapMouseup" @mousemove="wrapMouseMove" @mousedown="wrapMousedown">
                <div class="drop-bg" ref="dropBg" id="dropCanvas" @drop="drop($event,'item')" @dragover="allowDrop($event)" @click.self="clearActiveItem"  
                    :style="`transform:scale(${zoom});width:${selectStore.platW}px;height:${selectStore.platH}px;background-image: url('${selectStore.imageUrl}');background-color: ${selectStore.background};background-size:100% 100%;border: 1px solid  ${selectStore.borderColor};`">
                    <vdr
                        v-for="(item,index) in storehouseDomList" 
                        :key="index" 
                        :active="item.no == activeItem.no"
                        :preventDeactivation="true"
                        :w="item.width" 
                        :h="item.height" 
                        :x="item.x"
                        :y="item.y"
                        :minw="1" 
                        :minh="1" 
                        :snap="true" 
                        :snap-tolerance="1"
                        :is-conflict-check="true"
                        @activated="onActivated(item)"
                        @dragging="(x, y) => onDrag(x, y, item)" 
                        @resizing="(x, y, width, height) => onResize(x, y, width, height, item)" 
                        :parent="true"
                        :style="`background-color: ${item.background};background-image: url('${item.imageUrl}');background-size:100% 100%;border: 1px solid  ${item.borderColor};`"
                        >
                        <p style="text-align:center">{{item.no}}</p>
                    </vdr>
                </div>
            </div>
        </div>
        <!-- 右侧属性区 -->
        <el-drawer
            :title="(activeItem.category==2?'库区：':'库位：')+activeItem.no+'属性内容'"
            :visible.sync="attributeDrawer"
            :modal="false"
            :size="300">
            <div style="padding:16px">
                <div>
                    <div style="padding-bottom:8px">背景</div>
                    <el-radio-group v-if="activeItem.category == 2" v-model="backgroundType" style="margin-bottom: 30px;">
                        <el-radio-button label="color">纯色颜色</el-radio-button>
                        <el-radio-button label="image">图片</el-radio-button>
                    </el-radio-group>
                    <div v-if="backgroundType=='color'" class="flex-row-between">
                        <div class="flex-row">填充： <el-color-picker v-model="activeItem.background" show-alpha></el-color-picker></div>
                        <div class="flex-row">边界： <el-color-picker v-model="activeItem.borderColor" show-alpha></el-color-picker></div>
                    </div>
                    <div v-if="backgroundType=='image'">
                        <el-upload
                            :name="upload.name"
                            :data="upload.data"
                            class="avatar-uploader"
                            ref="upload"
                            :show-file-list="false"
                            :limit="1"
                            accept=".png,.jpg,.jpeg"
                            :headers="upload.headers"
                            :action="upload.url"
                            :before-upload="beforeAvatarUpload"
                            :on-progress="handleFileUploadProgress"
                            :on-success="handleFileSuccess">
                            <img v-if="activeItem.imageUrl" :src="activeItem.imageUrl" class="avatar">
                            <el-button v-if="activeItem.imageUrl" size="small" type="primary" @click.stop="delImage" style="margin-top:6px">
                                <i class="el-icon-delete"></i>删除
                            </el-button>
                            <i v-else class="el-icon-plus avatar-uploader-icon"></i>
                        </el-upload>
                    </div>
                </div>
                <el-divider content-position="left"></el-divider>
                <div>
                    <div style="padding-bottom:8px">变换</div>
                    <div style="padding-bottom:8px">
                        <span class="text">W： </span>   <el-input-number v-model='activeItem.width' :min="1" :controls="false" />
                    </div>
                    <div style="padding-bottom:8px">
                        <span class="text">H： </span>  <el-input-number v-model='activeItem.height' :min="1" :controls="false" />
                    </div>
                    <div style="padding-bottom:8px">
                        <span class="text">X： </span> <el-input-number v-model='activeItem.x' :min="0" :controls="false" />
                    </div>
                    <div style="padding-bottom:8px">
                        <span class="text">Y： </span> <el-input-number v-model='activeItem.y' :min="0" :controls="false" />
                    </div>
                </div>
                <el-divider content-position="left"></el-divider>
                <div class="flex-row-end">
                    <!-- <el-button type="primary">保存</el-button> -->
                    <el-button type="danger" @click="deleteItem">删除</el-button>
                </div>
            </div>
        </el-drawer>
    </div>

    <!-- 右侧菜单 -->
    <div ref="rightMenu" v-if="rightMenuVisible" class="right-menu">
        <div @click="deleteItem">删除</div>
    </div>
  </div>
</template>
  
  <script>
import draggable from "vuedraggable"
import vdr from 'vue-draggable-resizable-gorkys'
import 'vue-draggable-resizable-gorkys/dist/VueDraggableResizable.css'
import { getToken } from "@/utils/auth";

import { selectStoreHouseByTree, getInfoByStorehouseNo, getInfoByStorehouseAreaNo, putStorehousePlat, putStorehouseAreaPlat, uploadStoreHouseArea } from "@/api/basic/storehouse";


export default {
  name: "StorehousePlanView",

  components: {
    draggable,vdr
  },

  data() {
    const that = this;
    return {
        storeHouseTree:[],
        storehouseDomList:[
            // {
            //     no:'kq003',
            //     width: 100,
            //     height: 100,
            //     x: 100,
            //     y: 100,
            //     background:'rgba(124,235,224,0.4)',
            //     borderColor:'rgba(38, 166, 154, 1)'
            // }
        ],
        storehouseDomListOnlyRead:[],
        activeItem:{},
        backgroundType:'color',
        defaultProps: {
          children: 'childList',
          label: 'no'
        },
        //   draggableWrap:'block',
        selectStore: {},
        attributeDrawer: false,
        // 导入参数
        upload: {
            name:'storeHouseAreafile',
            // 是否显示弹出层（用户导入）
            open: false,
            // 弹出层标题（用户导入）
            title: "",
            // 是否禁用上传
            isUploading: false,
            // 设置上传的请求头部
            headers: { Authorization: "Bearer " + getToken() },
            data:{ storeHouseAreaNo: ''},
            // 上传的地址
            url: process.env.VUE_APP_BASE_API + "/basic/storehouseAreaPlat/uploadStoreHouseArea"
        },
        rightMenuVisible: false, // 右侧菜单显示控制
        zoom:'100%', // 画布缩放比例
        onSpace: false, // 是否按下空格键
        wrapXY:{},
    }
  },
  created(){
    this.selectStoreHouseByTree()
    // 鼠标右键菜单
    const that = this;
    document.addEventListener("contextmenu",(e)=>{
        console.log(e)
        if(e.target._prevClass.indexOf('vdr')!=-1){
            e.preventDefault();
            if(that.activeItem.no){
                that.rightMenuVisible = true;
                that.$nextTick(()=>{
                    that.$refs.rightMenu.style.left = e.clientX+'px';
                    that.$refs.rightMenu.style.top = e.clientY+'px';
                })
            }
        }
    })
    document.addEventListener("click",(e)=>{
        this.rightMenuVisible = false
    })
    document.onkeydown = (e)=> {
        if(e.code == "Space"){
            that.onSpace = true
            that.$refs.dropWrap.style.cursor = "move"
        }
    }
    document.onkeyup = (e)=> {
        if(e.code == "Space"){
            that.onSpace = false
            that.$refs.dropWrap.style.cursor = "default"
        }
    }
  },

  methods: {
    // 获取左侧仓库树形数据
    selectStoreHouseByTree(){
        selectStoreHouseByTree(this.$route.params.storeHouseNo).then(res=>{
            this.storeHouseTree = res.data
            // this.$nextTick(()=>{
            //     this.$refs.storeTree.setCheckedKeys([res.data[0].no])
            // })
            this.handleNodeClick(res.data[0],{isLeaf: false})
        })
    },
    dragStart(item){
      console.log('dragStart')
      console.log(item)
      
      this.dragItem = item
    },
    dragEnd(e){
      console.log('dragEnd')
    //   console.log(e)
    },
    dragOver(e) {
    //   console.log('dragOver')
    //   console.log('dragOver'+JSON.stringify(e))
    },
    wrapMouseup(e) {
      if(this.onSpace) {
        this.$set(this,'wrapXY',{})
      }
    },
    // 根据鼠标移动的位置 计算drogBg的位置
    wrapMouseMove(e) {
      if(this.onSpace && this.wrapXY) {
        let left =  - (this.wrapXY.x - e.clientX)
        this.$refs.dropBg.style.left = left + 'px'
        let top =  - (this.wrapXY.y - e.clientY)
        this.$refs.dropBg.style.top = top + 'px'
      }
    },
    // 记录鼠标按下时 dropBg与鼠标的相对位置
    wrapMousedown(e){
      if(this.onSpace) {
        this.$set(this,'wrapXY',{x: e.clientX - parseFloat(this.$refs.dropBg.style.left || 0), y: e.clientY - parseFloat(this.$refs.dropBg.style.top || 0) })
      }
    },
    cloneDefaultField(e){
        return JSON.parse(JSON.stringify(e));
    },
    // 允许放下拖拽 (放下库区库位)
    allowDrop(ev) {
      ev.preventDefault();
    },
    // 放下事件
    drop(ev, item) {
        ev.preventDefault();
        if(this.dragItem.no) {
            // 判断当前拖拽元素在当前选中的仓库/库区内
            let isInStore = this.selectStore.childList.findIndex(item=>item.no == this.dragItem.no)
            if(isInStore==-1){
                this.$modal.msgError('当前拖拽的元素不属于此仓库/库区')
                return
            }
            // 同时只能存在一个库区/库位
            let hasItem = this.storehouseDomList.findIndex(item => item.no == this.dragItem.no)
            if(hasItem==-1){
                this.storehouseDomList.push({
                    no: this.dragItem.no,
                    category: this.dragItem.category,
                    width: 100,
                    height: 100,
                    x: 100,
                    y: 100,
                    background:'rgba(124,235,224,0.4)',
                    borderColor:'rgba(38, 166, 154, 1)'
                })
            }else{
                this.$modal.msgError('已存在')
            }
        }
    //   let treeNode = ev.target;
    //   if (treeNode) {
    //     treeNode.appendChild(this.dom);
    //   }
    },
    // 获取仓库信息
    getInfoByStorehouseNo(data){
        getInfoByStorehouseNo(data.no).then(res=>{
            this.selectStore = {...this.selectStore, imageUrl:res.data.platImg, id:res.data.id, platW:res.data.platW, platH:res.data.platH}
            if(Array.isArray(JSON.parse(res.data.platContent))){
                this.$set(this,'storehouseDomList', JSON.parse(res.data.platContent))
                this.$set(this,'storehouseDomListOnlyRead', JSON.parse(res.data.platContent))
            } 
        })
    },
    // 获取库区信息
    getInfoByStorehouseAreaNo(data){
        console.log('getInfoByStorehouseAreaNo')
        getInfoByStorehouseAreaNo(data.no).then(res=>{
            // imageUrl:res.data.platImg,
            this.selectStore = {...this.selectStore, id:res.data.id}
            if(Array.isArray(JSON.parse(res.data.platContent))) this.$set(this,'storehouseDomList', JSON.parse(res.data.platContent))
        })
    },
    // 树形点击事件
    handleNodeClick(data, node, tree) {
        // 如果是叶子节点（库位），则不能编辑
        if(node.isLeaf) return
        if(!this.selectStore.no){
            // 当前无选中，点击选择时
            this.selectStore = {...data, background:'rgba(124, 235, 224, 0.4)', borderColor: '#26A69A'}
            if(data.category ==1){
                this.getInfoByStorehouseNo(data)
            }else{
                this.getInfoByStorehouseAreaNo(data)
            }
            this.$set(this,'storehouseDomList',[])
        }else{
            // 当前已有选中的仓库、库区
            if(this.selectStore.no == data.no) return
            this.$modal.confirm('是否切换仓库/库区？(未保存数据会丢失哦)').then(()=>{
                // 选中仓库、库区
                if(data.category ==2){
                    // 如果是库区，还需要将其长宽背景图加进来哦
                    let selectDropInfo = this.storehouseDomListOnlyRead.find(item=>data.no == item.no)
                    this.selectStore = {...data, imageUrl:selectDropInfo.imageUrl||'', platW:selectDropInfo.width||100, platH:selectDropInfo.height||100, background:selectDropInfo.background||'rgba(124, 235, 224, 0.4)', borderColor: selectDropInfo.borderColor||'#26A69A'}
                } else {
                    this.selectStore = {...data, background:'rgba(124, 235, 224, 0.4)', borderColor: '#26A69A'}
                }
                this.$set(this,'storehouseDomList',[])
                this.clearActiveItem()
                if(data.category ==1){
                    this.getInfoByStorehouseNo(data)
                }else{
                    this.getInfoByStorehouseAreaNo(data)
                }
            }).catch((e)=>{
                this.expandNodes(this.$refs.storeTree.store.root);
            })
        }
    },
    // 底图(仓库、库区)长宽改变时
    changeDropBg(){
        this.$set(this,'storehouseDomList',[])
        this.clearActiveItem()
        if(this.selectStore.category ==1){
            this.getInfoByStorehouseNo(this.selectStore)
        }else{
            this.getInfoByStorehouseAreaNo(this.selectStore)
        }
    },
    // 遍历树形数据，设置每一项的expanded属性，实现展开收起
    expandNodes(node) {
        if(node.key == this.selectStore.no){
            node.expanded = true;
        }else{
            node.expanded = false;
        }
        for (let i = 0; i < node.childNodes.length; i++) {
            if(node.childNodes[i].key == this.selectStore.no){
                node.expanded = true;
            }
            if (node.childNodes[i].childNodes.length > 0) {
                this.expandNodes(node.childNodes[i]);
            }
        }
    },
    // 单击
    onActivated(item){
        console.log(item)
        this.$set(this,'activeItem',item)
        this.upload.data.storeHouseAreaNo = item.no
        this.backgroundType = 'color'
        this.attributeDrawer = true
    },
    // 改变大小
    onResize: function (x, y, width, height, item) {
        item.x = x
        item.y = y
        item.width = width
        item.height = height
    },
    // 拖动
    onDrag: function (x, y, item) {
        item.x = x
        item.y = y
    },
    // 清空选中的元素
    clearActiveItem(){
        this.$set(this,'activeItem',{})
        this.attributeDrawer = false
    },
    // 上传前
    beforeAvatarUpload(){},
    // 文件上传中处理
    handleFileUploadProgress(event, file, fileList) {
      this.upload.isUploading = true;
    },
    // 文件上传成功处理
    handleFileSuccess(response, file, fileList) {
      this.$set(this.activeItem, 'imageUrl', process.env.VUE_APP_BASE_API + response.imgUrl)
      this.upload.open = false;
      this.upload.isUploading = false;
      this.$refs.upload.clearFiles();
    },
    delImage(){
      this.$set(this.activeItem, 'imageUrl', '')
    },
    // 删除元素
    deleteItem(){
        let index = this.storehouseDomList.findIndex(item=>item.no == this.activeItem.no)
        this.storehouseDomList.splice(index,1)
        this.rightMenuVisible = false;
    },
    // 切换画布比例
    handleCommand(zoom){
        this.zoom = zoom
    },
    save(){
        let params = {
            id: this.selectStore.id,
            platContent: JSON.stringify(this.storehouseDomList),
            platImg:'',
            platW: this.selectStore.platW,
            platH: this.selectStore.platH,
        }
        if(this.selectStore.category =='1'){
            putStorehousePlat(params).then(res=>{
                if(res.code == 200){
                    this.$modal.msgSuccess(res.msg)
                    this.changeDropBg()
                }else{
                    this.$modal.msgError(res.msg)
                }
            })
        }
        if(this.selectStore.category =='2'){
            putStorehouseAreaPlat(params).then(res=>{
                if(res.code == 200){
                    this.$modal.msgSuccess(res.msg)
                }else{
                    this.$modal.msgError(res.msg)
                }
            })
        }
    },
  },
}
</script>

<style lang="scss" scoped>
.flex-row-start-start{
    display: flex;
    flex-direction: row;
    justify-content: flex-start;
    align-content: flex-start;
}
.flex-row-between{
    display: flex;
    flex-direction: row;
    justify-content: space-between;
    align-content: center;
}
.flex-row{
    display: flex;
    flex-direction: row;
    justify-content: center;
    align-content: center;
}
.avatar-uploader .el-upload {
    border: 1px dashed #d9d9d9;
    border-radius: 6px;
    cursor: pointer;
    position: relative;
    overflow: hidden;
  }
  .avatar-uploader .el-upload:hover {
    border-color: #409EFF;
  }
  .avatar-uploader-icon {
    font-size: 28px;
    color: #8c939d;
    width: 178px;
    height: 178px;
    line-height: 178px;
    text-align: center;
  }
  .avatar {
    width: 178px;
    height: 178px;
    display: block;
  }

  .el-drawer__wrapper{
    left: calc(100vw - 334px);
    width: 334px;
  }
  .drop-wrap{
    width: 100%;
    height: calc(100vh - 164px);
    background: #f6f6f6;
    margin-top: 10px;
    overflow: hidden;
    position: relative;
    .drop-bg{
        width:700px;
        height:500px;
        border: 1px solid #26A69A; 
        background: rgba(124,235,224,0.4);
        transform-origin: 0 0;
        position: absolute;
        left: 0;
        top: 0;
    }
  }
  .right-menu{
    position: fixed;
    width: 65px;
    background: #FFFFFF;
    box-shadow: 0px 3px 6px 1px rgba(43,43,43,0.16);
    border-radius: 4px 4px 4px 4px;
    div{
        cursor: pointer;
        height: 28px;
        line-height:28px;
        text-align: center;
    }
    div:hover{
        background: rgba(38,166,154,0.16);
        color:#26A69A
    }
  }
  .text{
    width: 30px;
    display: inline-block;
  }
</style>